<?php

namespace common\models;

use common\cache\DictCache;
use common\components\OrderBehavior;
use common\helpers\commonApi;
use common\helpers\PageApi;
use common\helpers\QueueApi;
use common\helpers\RedisApi;
use common\helpers\TransformApi;
use Yii;
use yii\db\Exception;

/**
 * This is the model class for table "{{%order_receiv}}".
 *
 * @property int $id
 * @property string|null $order_sn 订单号
 * @property int|null $userid 接单用户
 * @property int|null $status 状态
 * @property string|null $create_time 创建时间
 * @property string|null $update_time 修改时间
 * @property string|null $run_info 跑腿信息
 * @property string|null $pickup_time 取货时间
 * @property string|null $deliver_time 送达时间
 * @property string|null $cancel_time 取消时间
 * @property string|null $is_receipt 是否收货 0:否 1:是
 * @property string|null $receipt_time 收货时间
 * @property float|null $delivery_fee 配送
 */
class OrderReceiv extends BaseModel
{
    /**
     * {@inheritdoc}
     */
    public static function tableName()
    {
        return '{{%order_receiv}}';
    }

    /**
     * {@inheritdoc}
     */
    public function rules()
    {
        return [
            [['userid', 'status'], 'integer'],
            [['create_time', 'update_time', 'pickup_time', 'deliver_time', 'cancel_time', 'is_receipt', 'receipt_time'], 'safe'],
            [['run_info'], 'string'],
            [['order_sn'], 'string', 'max' => 255],
            [['delivery_fee'], 'number'],
        ];
    }

    /**
     * {@inheritdoc}
     */
    public function attributeLabels()
    {
        return [
            'id' => 'ID',
            'order_sn' => '订单号',
            'userid' => '接单用户',
            'status' => '状态',
            'create_time' => '创建时间',
            'update_time' => '修改时间',
            'run_info' => '跑腿信息',
            'pickup_time' => '取货时间',
            'deliver_time' => '送达时间',
            'cancel_time' => '取消时间',
            'is_receipt' => '是否收货 0:否 1:是',
            'receipt_time' => '收货时间',
            'delivery_fee' => '配送费',
        ];
    }

    /**
     * 接单
     * @param $order_sn 订单号
     * @param $userid 用户id
     * @return array|bool
     */
    public function taking($order_sn,$userid)
    {
        $exit = self::find()->where(['order_sn'=>$order_sn])->one();
        if ($exit){
            return commonApi::message('请勿重复接单',false);
        }
        $order = Order::find()->where(['order_sn'=>$order_sn,'run_status'=>0,'order_status'=>1])->one();
        if (!$order){
            return commonApi::message('订单不能进行抢单');
        }
        $run = (new Running())->isRunn($userid);
        if (!$run['is_runn']){
            return commonApi::message('暂不能接单',false);
        }
        if ($run['campus_id']!==$order->campus_id){
            return commonApi::message('不能进行跨校区接单',false);
        }
        $system = System::getModel();
        $max_run_num = $system->max_run_num??0;
        if ($max_run_num>0){
            $count = self::find()->where(['userid'=>$userid,'status'=>0])->count();
            $count = $count??0;
            if ($count>$max_run_num){
                return commonApi::message('最多可以接'.$max_run_num.'单',false);
            }
        }
        if ($order->snatch_sex){
            if ($order->snatch_sex!==$run['info']['sex']){
                $astrict_sex = DictCache::get('astrict_sex');
                $sex = $astrict_sex[$order->snatch_sex]??'';
                return commonApi::message("该订单要求【{$sex}】接单",false);
            }
        }
        $redisKey = 'taking_'.$order_sn;
        $redis = new RedisApi($redisKey);
        $result = $redis->verificLock();
        if ($result){
            return commonApi::message('请勿重复操作！',false);
        }
        $redis->lock($order_sn);
        $redis->expire(120);
        $order->order_status = 2;
        $order->run_userid = $userid;
        $order->run_status = 1;
        $model = new self();
        $model->order_sn = $order_sn;
        $model->userid = $userid;
        $model->status = 0;
        $model->run_info = json_encode($run['info']);
        $model->delivery_fee = $order->delivery_fee;
        TransformApi::tx(function ()use ($order,$model,$run){
            if ($model->save()&&$order->save()){
                OrderLog::add(1,$order->order_sn,$model->userid,'','跑腿接单',"【{$run['runn_name']}】跑腿接单");
                return commonApi::message('接单成功');
            }
            throw new Exception('接单失败');
        },$result);
        $redis->unlock();
        return $result;
    }

    /**
     * 我的抢单
     * @param $userid
     * @param $status
     * @param $page
     * @return array
     */
    public function takingList($userid,$status,$page)
    {
        $query = self::find()
            ->select(['order_sn','id','status'])
            ->where(['userid'=>$userid])
            ->andFilterWhere(['status'=>$status])
            ->orderBy(['create_time'=>SORT_DESC]);
        $data = PageApi::apiPage($query,$page);
        $order_sns = array_column($data['data'],'order_sn');
        $order = Order::find()
            ->select(['id','campus_id','delivery_info','receipt_info','create_time','pay_amount','order_sn'])
            ->where(['order_sn'=>$order_sns])
            ->asArray()->all();
        $ids = array_column($order,'id');
        $campus_ids = array_column($order,'campus_id');
        $order = array_column($order,null,'order_sn');
        $campus = new Campus();
        $campusName = $campus->getCampusName($campus_ids);
        $orderGoods = new OrderGoods();
        $goods = $orderGoods->getList($ids);
        $receiv_status = DictCache::get('receiv_status');
        $arr = [];
        foreach ($data['data'] as $datum){
            $orderInfo = $order[$datum['order_sn']]??[];
            $receipt_info = $orderInfo['receipt_info']??'';
            $receipt_info = json_decode($receipt_info,true);
            $delivery_info = $orderInfo['delivery_info']??'';
            $delivery_info = json_decode($delivery_info,true);
            $spec = $goods[$orderInfo['id']]??[];
            $spec = array_column($spec,'good_num');
            $total_num = array_sum($spec);
            $one = [
                'campus_name'=>$campusName[$orderInfo['campus_id']]??'',
                'order_sn'=>$datum['order_sn'].'_'.$datum['id'],
                'create_time'=>$orderInfo['create_time']??'',
                'goods'=>$goods[$orderInfo['id']]??[],
                'receipt'=>$receipt_info['address']??'',
                'delivery'=>$delivery_info['address']??'',
                'total_num'=>$total_num,
                'pay_amount'=>$orderInfo['pay_amount']??0,
                'total_amount'=>$orderInfo['total_amount']??0,
                'delivery_fee'=>$orderInfo['delivery_fee']??0,
                'status'=>$datum['status'],
                'status_title'=>$receiv_status[$datum['status']]??'',
            ];
            $arr[] = $one;
        }
        $data['data'] = $arr;
        return commonApi::message('ok',true,$data);
    }

    /**
     * 取货
     * @param $order_sn
     * @param $userid
     * @return array|mixed
     */
    public function pickup($order_sn,$userid)
    {
        $orderI = explode('_',$order_sn);
        $order_sn = $orderI[0];
        $selfId = $orderI[1]??'';
        $model = self::find()->where(['order_sn'=>$order_sn,'userid'=>$userid])->andFilterWhere(['id'=>$selfId])->orderBy(['create_time'=>SORT_DESC])->one();
        if (!$model){
            return commonApi::message('暂无该订单接单信息',false);
        }
        if ($model->status!==0){
            return commonApi::message('该订单不支持取货',false);
        }
        $order = Order::find()->where(['order_sn'=>$model->order_sn])->one();
        if (!$order){
            return commonApi::message('订单不存在',false);
        }
        $runn = (new Running())->isRunn($userid);
        $redisKey = 'pickup_'.$order_sn;
        $redis = new RedisApi($redisKey);
        if ($redis->verificLock()){
            return commonApi::message('正在操作中',false);
        }
        $redis->lock($order_sn);
        $redis->expire(120);
        $model->status = 1;
        $model->pickup_time = date('Y-m-d H:i:s');
        $order->order_status = 3;
        TransformApi::tx(function ()use ($model,$userid,$runn,$order){
            if ($model->save()&&$order->save()){
                OrderLog::add(1,$model->order_sn,$userid,$runn['runn_name'],'跑腿取货',"【{$runn['runn_name']}】取货");
                return commonApi::message('取货成功');
            }
            throw new Exception('取货失败');
        },$result);
        $redis->unlock();
        return $result;
    }

    /**
     * 送达
     * @param $order_sn
     * @param $userid
     * @return array|mixed
     */
    public function deliver($order_sn,$userid)
    {
        $orderI = explode('_',$order_sn);
        $order_sn = $orderI[0];
        $selfId = $orderI[1]??'';
        $model = self::find()->where(['order_sn'=>$order_sn,'userid'=>$userid])->andFilterWhere(['id'=>$selfId])->orderBy(['create_time'=>SORT_DESC])->one();
        if (!$model){
            return commonApi::message('暂无该订单接单信息',false);
        }
        if ($model->status!==1){
            return commonApi::message('该订单不支持送达',false);
        }
        $order = Order::find()->where(['order_sn'=>$model->order_sn])->one();
        if (!$order){
            return commonApi::message('订单不存在',false);
        }
        $runn = (new Running())->isRunn($userid);
        $redisKey = 'deliver_'.$order_sn;
        $redis = new RedisApi($redisKey);
        $redis->unlock();
        if ($redis->verificLock()){
            return commonApi::message('正在操作中',false);
        }
        $redis->lock($order_sn);
        $redis->expire(120);
        $model->status = 2;
        $model->deliver_time = date('Y-m-d H:i:s');
        $order_receiv = System::getModel()->order_receiv??0;
        $order_receiv = $order_receiv*60*60;
        $order->order_status = 4;
        TransformApi::tx(function ()use ($model,$userid,$runn,$order_receiv,$order){
            if ($model->save()&&$order->save()){
                OrderLog::add(1,$model->order_sn,$userid,$runn['runn_name'],'订单送达',"【{$runn['runn_name']}】送达");
                if ($order_receiv>0){
                    $callable = new OrderBehavior([
                        'method' => OrderBehavior::ORDER_RECEIV,
                        'params' => ['order_sn'=>$model->order_sn],
                    ]);
                    (new QueueApi())->delay($order_receiv,$callable);
                }
                return commonApi::message('送达成功');
            }
            throw new Exception('送达失败');
        },$result);
        $redis->unlock();
        return $result;
    }

    /**
     * 取消
     * @param $order_sn
     * @param $userid
     * @return array|mixed
     */
    public function cancel($order_sn,$userid)
    {
        $orderI = explode('_',$order_sn);
        $order_sn = $orderI[0];
        $selfId = $orderI[1]??'';
        $model = self::find()->where(['order_sn'=>$order_sn,'userid'=>$userid])->andFilterWhere(['id'=>$selfId])->orderBy(['create_time'=>SORT_DESC])->one();
        if (!$model){
            return commonApi::message('暂无该订单接单信息',false);
        }
        if (!in_array($model->status,[0,1])){
            return commonApi::message('该订单不支持取消',false);
        }
        $order = Order::findOne(['order_sn'=>$order_sn]);
        if (!$order){
            return commonApi::message('订单不存在',false);
        }
        $runn = (new Running())->isRunn($userid);
        $redisKey = 'cancel_'.$order_sn;
        $redis = new RedisApi($redisKey);
        if ($redis->verificLock()){
            return commonApi::message('正在操作中',false);
        }
        $redis->lock($order_sn);
        $redis->expire(120);
        $model->status = 3;
        $model->cancel_time = date('Y-m-d H:i:s');
        $order->run_status = 0;
        $order->run_userid = null;
        $order->order_status = 1;
        TransformApi::tx(function ()use ($model,$userid,$runn,$order){
            if ($model->save()&&$order->save()){
                OrderLog::add(1,$model->order_sn,$userid,$runn['runn_name'],'接单取消',"【{$runn['runn_name']}】接单取消");
                return commonApi::message('取消成功');
            }
            throw new Exception('取消失败');
        },$result);
        $redis->unlock();
        return $result;
    }

    /**
     * 详情
     * @param $orderSn
     * @param $userid
     * @return array
     */
    public function getDetails($orderSn,$userid)
    {
        $orderI = explode('_',$orderSn);
        $orderSn = $orderI[0];
        $selfId = $orderI[1]??'';
        $order = Order::find()->where(['order_sn'=>$orderSn])->one();
        if (!$order){
            return commonApi::message('订单不存在!',false);
        }
        $orderGoods = new OrderGoods();
        $goods = $orderGoods->getList($order->id);
        $addrAn = $order->addrAn($order->delivery_info,$order->receipt_info,$order->delivery_method);
        $data = [
            'goods'=>$goods[$order->id]??[],
            'total_amount'=>$order->total_amount,
            'pay_amount'=>$order->pay_amount,
            'discount_amount'=>$order->discount_amount,
            'delivery_fee'=>$order->delivery_fee,
            'user_remarks'=>$order->user_remarks,
        ];
        $run_status = DictCache::get('run_status');
        $data['delivery_info'] = $addrAn['delivery_info'];
        $data['receipt_info'] = $addrAn['receipt_info'];
        $data['run_status_title'] = '';
        $data['run_status'] = (int)$order->run_status;
        if ($order->order_status>0){
            $data['run_status_title'] = $run_status[$order->run_status]??'';
        }
        $data['status'] = -1;
        $data['status_title'] = '';
        $data['run_info'] = [];
        if ($order->run_userid==$userid){
            $receiv_status = DictCache::get('receiv_status');
            $receiv = OrderReceiv::find()
                ->where(['order_sn'=>$orderSn,'userid'=>$userid])
                ->andFilterWhere(['id'=>$selfId])
                ->orderBy(['create_time'=>SORT_DESC])
                ->asArray()->one();
            $data['status'] = $receiv['status']??'';
            $data['status'] = (int)$receiv['status'];
            $data['status_title'] = $receiv_status[$receiv['status']]??'';
            $run_info = json_decode($receiv['run_info'],true);
            $data['run_info']['name'] = $run_info['name'];
            $data['run_info']['mobile'] = $run_info['mobile'];
        }
        return commonApi::message('ok',true,$data);
    }
}

